/**
 * 对bitmap.h的测试。
 */
#include <stdio.h>
#include <stdlib.h>

#include <cds/bitmap.h>
#include "test_tools.h"

static void bitmap_create_test(void)
{
    size_t test_sizes[] = {
        63745, 40386, 59651, 20419, 46532, 38983, 24648, 61896, 16842, 1, 2,
        6158, 30929, 7064, 33373, 31072, 4964, 33574, 12839, 16426, 58859, 
        56490, 59372, 64943, 58096, 56880, 21874, 33328, 38644, 33139, 59830, 
        19505, 17336, 41403, 4, 8, 16
    };
    size_t test_sizes_len = sizeof(test_sizes) / sizeof(size_t);
    size_t cnt = 0;
    int ret = 0;

    for (cnt = 0; cnt < test_sizes_len; cnt++) {
        struct bitmap *bm = CREATE_BITMAP_WITH_PADDING((test_sizes[cnt] + 7) & (~7UL));
        if (bm == NULL) {
            LOG_TEST_FAIL("failed to create bitmap! cnt: %zu, size: %zu\n", cnt, test_sizes[cnt]);
            break;
        }
        ret = BITMAP_FULLY_TEST(bm);
        if (ret != 0) {
            LOG_TEST_FAIL("invalid bitmap! cnt: %zu, size: %zu\n", cnt, test_sizes[cnt]);
            SHOW_BITMAP_ERROR_INFO(ret);
            DESTROY_BITMAP_WITH_PADDING(bm);
            break;
        }
        if (bitmap_size(bm) != (test_sizes[cnt] + 7) & (~7UL)) {
            LOG_TEST_FAIL("didn't get the right size! cnt: %zu, size: %zu, get_size: %zu\n", cnt, test_sizes[cnt], bitmap_size(bm));
            DESTROY_BITMAP_WITH_PADDING(bm);
            break;
        }
        if (!BITMAP_EMPTY_TEST(bm)) {
            LOG_TEST_FAIL("bitmap just created is not empty! cnt: %zu, size: %zu\n", cnt, test_sizes[cnt]);
            DESTROY_BITMAP_WITH_PADDING(bm);
            break;
        }
        bitmap_set_all(bm);
        if (!BITMAP_ALL_SET_TEST(bm)) {
            LOG_TEST_FAIL("bitmap after all set is not fully set! cnt: %zu, size: %zu\n", cnt, test_sizes[cnt]);
            DESTROY_BITMAP_WITH_PADDING(bm);
            break;
        }
        bitmap_clear_all(bm);
        if (!BITMAP_EMPTY_TEST(bm)) {
            LOG_TEST_FAIL("bitmap after reset is not empty! cnt: %zu, size: %zu\n", cnt, test_sizes[cnt]);
            DESTROY_BITMAP_WITH_PADDING(bm);
            break;
        }
        DESTROY_BITMAP_WITH_PADDING(bm);
    }

    if (cnt == test_sizes_len) {
        LOG_TEST_PASS("bitmaps of all sizes are successfully created!\n");
    }

    if (CREATE_BITMAP_WITH_PADDING(0) != NULL) {
        LOG_TEST_FAIL("bitmap's buffer size can not be 0!\n");
    } else {
        LOG_TEST_PASS("\n");
    }
}

/// 测试是否一个范围内的所有字节都为0xff
static int __is_all_bytes_full(void *bytes, size_t size)
{
    unsigned char *str = (unsigned char*)bytes;
    for (int i = 0; i < size; i++) {
        if (str[i] != 0xff) {
            return 0;
        }
    }
    return 1;
}

/// 测试是否一个范围内的所有字节都为0。
static int __is_all_bytes_empty(void *bytes, size_t size)
{
    unsigned char *str = (unsigned char*)bytes;
    for (int i = 0; i < size; i++) {
        if (str[i] != 0) {
            return 0;
        }
    }
    return 1;
}

static void bitmap_basic_test(void)
{
    struct bitmap *bm0 = CREATE_BITMAP_WITH_PADDING((1 + 7) & (~7UL));
    struct bitmap *bm1 = CREATE_BITMAP_WITH_PADDING((2 + 7) & (~7UL));
    struct bitmap *bm2 = CREATE_BITMAP_WITH_PADDING((8 + 7) & (~7UL));
    struct bitmap *bm3 = CREATE_BITMAP_WITH_PADDING((17 + 7) & (~7UL));

    struct bitmap *bm4 = CREATE_BITMAP_WITH_PADDING((1 + 7) & (~7UL));
    struct bitmap *bm5 = CREATE_BITMAP_WITH_PADDING((2 + 7) & (~7UL));
    struct bitmap *bm6 = CREATE_BITMAP_WITH_PADDING((8 + 7) & (~7UL));
    struct bitmap *bm7 = CREATE_BITMAP_WITH_PADDING((17 + 7) & (~7UL));

    unsigned char comps[32] = {
        0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff,
        0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80,
        0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f,
        0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
    unsigned long cnt = 0;
    int ret = 0;

    /// 一个比特一个比特地置位，并测试。
    for (cnt = 0; cnt < 8; cnt++)
    {
        bitmap_set_bit(bm0, cnt);
        bitmap_set_bit(bm4, 7 - cnt);
        ret = BITMAP_FULLY_TEST(bm0);
        if (ret != 0) {
            LOG_TEST_FAIL("bm0, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        ret = BITMAP_FULLY_TEST(bm4);
        if (ret != 0) {
            LOG_TEST_FAIL("bm4, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        if (*(unsigned char*)(bm0->buffer) != comps[cnt]) {
            LOG_TEST_FAIL("bm0, cnt: %zu\n", cnt);
            break;
        }
        if (*(unsigned char*)(bm4->buffer) != comps[15 - cnt]) {
            LOG_TEST_FAIL("bm4, cnt: %zu\n", cnt);
            break;
        }
    }
    if (cnt == 8) {
        LOG_TEST_PASS("8bits\n");
    }

    for (cnt = 0; cnt < 16; cnt++)
    {
        bitmap_set_bit(bm1, cnt);
        bitmap_set_bit(bm5, 15 - cnt);
        ret = BITMAP_FULLY_TEST(bm1);
        if (ret != 0) {
            LOG_TEST_FAIL("bm1, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        ret = BITMAP_FULLY_TEST(bm5);
        if (ret != 0) {
            LOG_TEST_FAIL("bm5, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        if (*(unsigned char*)(bm1->buffer + (cnt >> 3)) != comps[cnt & 7]) {
            LOG_TEST_FAIL("bm1, cnt: %zu\n", cnt);
            break;
        }
        if (*(unsigned char*)(bm5->buffer + 1 - (cnt >> 3)) != comps[15 - (cnt & 7)]) {
            LOG_TEST_FAIL("bm5, cnt: %zu\n", cnt);
            break;
        }
        if ((cnt >> 3) == 0) {
            if (*(unsigned char*)(bm1->buffer + 1) != 0) {
                LOG_TEST_FAIL("bm1, cnt: %zu\n", cnt);
                break;
            }
            if (*(unsigned char*)(bm5->buffer) != 0) {
                LOG_TEST_FAIL("bm5, cnt: %zu\n", cnt);
                break;
            }
        } else {
            if (*(unsigned char*)(bm1->buffer) != 0xff) {
                LOG_TEST_FAIL("bm1, cnt: %zu\n", cnt);
                break;
            }
            if (*(unsigned char*)(bm5->buffer + 1) != 0xff) {
                LOG_TEST_FAIL("bm5, cnt: %zu\n", cnt);
                break;
            }
        }
    }
    if (cnt == 16) {
        LOG_TEST_PASS("16bits\n");
    }

    for (cnt = 0; cnt < 64; cnt++)
    {
        bitmap_set_bit(bm2, cnt);
        bitmap_set_bit(bm6, 63 - cnt);
        ret = BITMAP_FULLY_TEST(bm2);
        if (ret != 0) {
            LOG_TEST_FAIL("bm2, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        ret = BITMAP_FULLY_TEST(bm6);
        if (ret != 0) {
            LOG_TEST_FAIL("bm6, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }

        unsigned long tmp = cnt >> 3;
        if (*(unsigned char*)(bm2->buffer + tmp) != comps[cnt & 7]) {
            LOG_TEST_FAIL("bm2, cnt: %zu\n", cnt);
            break;
        }
        if (*(unsigned char*)(bm6->buffer + 7 - tmp) != comps[15 - (cnt & 7)]) {
            LOG_TEST_FAIL("bm6, cnt: %zu\n", cnt);
            break;
        }
        if (!__is_all_bytes_full(bm2->buffer, tmp)) {
            LOG_TEST_FAIL("bm2. not full. cnt: %zu\n", cnt);
            break;
        }
        if (!__is_all_bytes_empty(bm2->buffer + tmp + 1, 7 - tmp)) {
            LOG_TEST_FAIL("bm2. not empty. cnt: %zu\n", cnt);
            break;
        }

        if (!__is_all_bytes_empty(bm6->buffer, 7 -tmp)) {
            LOG_TEST_FAIL("bm6. not empty. cnt: %zu\n", cnt);
            break;
        }
        if (!__is_all_bytes_full(bm6->buffer + 8 - tmp, tmp)) {
            LOG_TEST_FAIL("bm6. not full. cnt: %zu\n", cnt);
            break;
        }
    }
    if (cnt == 64) {
        LOG_TEST_PASS("64bits\n");
    }

    for (cnt = 0; cnt < 136; cnt++)
    {
        bitmap_set_bit(bm3, cnt);
        bitmap_set_bit(bm7, 135 - cnt);
        ret = BITMAP_FULLY_TEST(bm3);
        if (ret != 0) {
            LOG_TEST_FAIL("bm3, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        ret = BITMAP_FULLY_TEST(bm7);
        if (ret != 0) {
            LOG_TEST_FAIL("bm7, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        
        unsigned long tmp = cnt >> 3;
        if (*(unsigned char*)(bm3->buffer + tmp) != comps[cnt & 7]) {
            LOG_TEST_FAIL("bm3, cnt: %zu\n", cnt);
            break;
        }
        if (*(unsigned char*)(bm7->buffer + 16 - tmp) != comps[15 - (cnt & 7)]) {
            LOG_TEST_FAIL("bm7, cnt: %zu\n", cnt);
            break;
        }
        if (!__is_all_bytes_full(bm3->buffer, tmp)) {
            LOG_TEST_FAIL("bm3. not full. cnt: %zu\n", cnt);
            break;
        }
        if (!__is_all_bytes_empty(bm3->buffer + tmp + 1, 16 - tmp)) {
            LOG_TEST_FAIL("bm3. not empty. cnt: %zu\n", cnt);
            break;
        }

        if (!__is_all_bytes_empty(bm7->buffer, 16 -tmp)) {
            LOG_TEST_FAIL("bm7. not empty. cnt: %zu\n", cnt);
            break;
        }
        if (!__is_all_bytes_full(bm7->buffer + 17 - tmp, tmp)) {
            LOG_TEST_FAIL("bm7. not full. cnt: %zu\n", cnt);
            break;
        }
    }
    if (cnt == 136) {
        LOG_TEST_PASS("136bits\n");
    }

    /// 一个比特一个比特地清除，并测试。
    for (cnt = 0; cnt < 8; cnt++)
    {
        bitmap_clear_bit(bm4, cnt);
        bitmap_clear_bit(bm0, 7 - cnt);
        ret = BITMAP_FULLY_TEST(bm0);
        if (ret != 0) {
            LOG_TEST_FAIL("bm0, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        ret = BITMAP_FULLY_TEST(bm4);
        if (ret != 0) {
            LOG_TEST_FAIL("bm4, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        if (*(unsigned char*)(bm0->buffer) != comps[23 - cnt]) {
            LOG_TEST_FAIL("bm0, cnt: %zu\n", cnt);
            break;
        }
        if (*(unsigned char*)(bm4->buffer) != comps[24 + cnt]) {
            LOG_TEST_FAIL("bm4, cnt: %zu\n", cnt);
            break;
        }
    }
    if (cnt == 8) {
        LOG_TEST_PASS("8bits\n");
    }

    for (cnt = 0; cnt < 16; cnt++)
    {
        bitmap_clear_bit(bm5, cnt);
        bitmap_clear_bit(bm1, 15 - cnt);
        ret = BITMAP_FULLY_TEST(bm1);
        if (ret != 0) {
            LOG_TEST_FAIL("bm1, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        ret = BITMAP_FULLY_TEST(bm5);
        if (ret != 0) {
            LOG_TEST_FAIL("bm5, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        if (*(unsigned char*)(bm1->buffer + 1 - (cnt >> 3)) != comps[23 - (cnt & 7)]) {
            LOG_TEST_FAIL("bm1, cnt: %zu\n", cnt);
            break;
        }
        if (*(unsigned char*)(bm5->buffer + (cnt >> 3)) != comps[24 + (cnt & 7)]) {
            LOG_TEST_FAIL("bm5, cnt: %zu\n", cnt);
            break;
        }
        if ((cnt >> 3) == 0) {
            if (*(unsigned char*)(bm1->buffer) != 0xff) {
                LOG_TEST_FAIL("bm1, cnt: %zu\n", cnt);
                break;
            }
            if (*(unsigned char*)(bm5->buffer + 1) != 0xff) {
                LOG_TEST_FAIL("bm5, cnt: %zu\n", cnt);
                break;
            }
        } else {
            if (*(unsigned char*)(bm1->buffer + 1) != 0) {
                LOG_TEST_FAIL("bm1, cnt: %zu\n", cnt);
                break;
            }
            if (*(unsigned char*)(bm5->buffer) != 0) {
                LOG_TEST_FAIL("bm5, cnt: %zu\n", cnt);
                break;
            }
        }
    }
    if (cnt == 16) {
        LOG_TEST_PASS("16bits\n");
    }

    for (cnt = 0; cnt < 64; cnt++)
    {
        bitmap_clear_bit(bm6, cnt);
        bitmap_clear_bit(bm2, 63 - cnt);
        ret = BITMAP_FULLY_TEST(bm2);
        if (ret != 0) {
            LOG_TEST_FAIL("bm2, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        ret = BITMAP_FULLY_TEST(bm6);
        if (ret != 0) {
            LOG_TEST_FAIL("bm6, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }

        unsigned long tmp = cnt >> 3;
        if (*(unsigned char*)(bm2->buffer + 7 - tmp) != comps[23 -(cnt & 7)]) {
            LOG_TEST_FAIL("bm2, cnt: %zu\n", cnt);
            break;
        }
        if (*(unsigned char*)(bm6->buffer + tmp) != comps[24 + (cnt & 7)]) {
            LOG_TEST_FAIL("bm6, cnt: %zu\n", cnt);
            break;
        }
        if (!__is_all_bytes_empty(bm2->buffer + 8 - tmp, tmp)) {
            LOG_TEST_FAIL("bm2. not empty. cnt: %zu\n", cnt);
            break;
        }
        if (!__is_all_bytes_full(bm2->buffer, 7 - tmp)) {
            LOG_TEST_FAIL("bm2. not full. cnt: %zu\n", cnt);
            break;
        }

        if (!__is_all_bytes_full(bm6->buffer + tmp + 1, 7 - tmp)) {
            LOG_TEST_FAIL("bm6. not full. cnt: %zu\n", cnt);
            break;
        }
        if (!__is_all_bytes_empty(bm6->buffer, tmp)) {
            LOG_TEST_FAIL("bm6. not empty. cnt: %zu\n", cnt);
            break;
        }
    }
    if (cnt == 64) {
        LOG_TEST_PASS("64bits\n");
    }

    for (cnt = 0; cnt < 136; cnt++)
    {
        bitmap_clear_bit(bm7, cnt);
        bitmap_clear_bit(bm3, 135 - cnt);
        ret = BITMAP_FULLY_TEST(bm3);
        if (ret != 0) {
            LOG_TEST_FAIL("bm3, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        ret = BITMAP_FULLY_TEST(bm7);
        if (ret != 0) {
            LOG_TEST_FAIL("bm7, cnt: %zu\n", cnt);
            SHOW_BITMAP_ERROR_INFO(ret);
            break;
        }
        
        unsigned long tmp = cnt >> 3;
        if (*(unsigned char*)(bm3->buffer + 16 - tmp) != comps[23 -(cnt & 7)]) {
            LOG_TEST_FAIL("bm3, cnt: %zu\n", cnt);
            break;
        }
        if (*(unsigned char*)(bm7->buffer + tmp) != comps[24 + (cnt & 7)]) {
            LOG_TEST_FAIL("bm7, cnt: %zu\n", cnt);
            break;
        }
        if (!__is_all_bytes_empty(bm3->buffer + 17 - tmp, tmp)) {
            LOG_TEST_FAIL("bm3. not empty. cnt: %zu\n", cnt);
            break;
        }
        if (!__is_all_bytes_full(bm3->buffer, 16 - tmp)) {
            LOG_TEST_FAIL("bm3. not full. cnt: %zu\n", cnt);
            break;
        }

        if (!__is_all_bytes_full(bm7->buffer + tmp + 1, 16 - tmp)) {
            LOG_TEST_FAIL("bm7. not full. cnt: %zu\n", cnt);
            break;
        }
        if (!__is_all_bytes_empty(bm7->buffer, tmp)) {
            LOG_TEST_FAIL("bm7. not empty. cnt: %zu\n", cnt);
            break;
        }
    }
    if (cnt == 136) {
        LOG_TEST_PASS("136bits\n");
    }

    /// 置位一块，并测试。
    bitmap_clear_all(bm0);
    bitmap_set_block(bm0, 0, 5);    // 0x3f
    ret = BITMAP_FULLY_TEST(bm0);
    if (ret != 0) {
        LOG_TEST_FAIL("bm0\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm0\n");
    }
    if (*(unsigned char*)(bm0->buffer) != 0x3f) {
        LOG_TEST_FAIL("bm0, %#X\n", *(unsigned char*)(bm0->buffer));
    } else {
        LOG_TEST_PASS("bm0\n");
    }
    bitmap_clear_all(bm0);
    bitmap_set_block(bm0, 3, 6);    // 0x78
    ret = BITMAP_FULLY_TEST(bm0);
    if (ret != 0) {
        LOG_TEST_FAIL("bm0\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm0\n");
    }
    if (*(unsigned char*)(bm0->buffer) != 0x78) {
        LOG_TEST_FAIL("bm0, %#X\n", *(unsigned char*)(bm0->buffer));
    } else {
        LOG_TEST_PASS("bm0\n");
    }
    bitmap_clear_all(bm0);
    bitmap_set_block(bm0, 2, 7);    // 0xfc
    ret = BITMAP_FULLY_TEST(bm0);
    if (ret != 0) {
        LOG_TEST_FAIL("bm0\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm0\n");
    }
    if (*(unsigned char*)(bm0->buffer) != 0xfc) {
        LOG_TEST_FAIL("bm0, %#X\n", *(unsigned char*)(bm0->buffer));
    } else {
        LOG_TEST_PASS("bm0\n");
    }
    bitmap_clear_all(bm0);
    bitmap_set_block(bm0, 0, 7);    // 0xff
    ret = BITMAP_FULLY_TEST(bm0);
    if (ret != 0) {
        LOG_TEST_FAIL("bm0\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm0\n");
    }
    if (*(unsigned char*)(bm0->buffer) != 0xff) {
        LOG_TEST_FAIL("bm0, %#X\n", *(unsigned char*)(bm0->buffer));
    } else {
        LOG_TEST_PASS("bm0\n");
    }
    bitmap_clear_all(bm0);
    bitmap_set_block(bm0, 3, 3);    // 0x08
    ret = BITMAP_FULLY_TEST(bm0);
    if (ret != 0) {
        LOG_TEST_FAIL("bm0\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm0\n");
    }
    if (*(unsigned char*)(bm0->buffer) != 0x08) {
        LOG_TEST_FAIL("bm0, %#X\n", *(unsigned char*)(bm0->buffer));
    } else {
        LOG_TEST_PASS("bm0\n");
    }

    bitmap_clear_all(bm1);
    bitmap_set_block(bm1, 0, 12);    // 0x1f, 0xff
    ret = BITMAP_FULLY_TEST(bm1);
    if (ret != 0) {
        LOG_TEST_FAIL("bm1\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm1\n");
    }
    if (((unsigned char*)(bm1->buffer))[1] != 0x1f 
        || ((unsigned char*)(bm1->buffer))[0] != 0xff) {
        LOG_TEST_FAIL("bm1, %#X %#X\n", ((unsigned char*)(bm1->buffer))[1], ((unsigned char*)(bm1->buffer))[0]);
    } else {
        LOG_TEST_PASS("bm1\n");
    }
    bitmap_clear_all(bm1);
    bitmap_set_block(bm1, 4, 8);    // 0x01, 0xf0
    ret = BITMAP_FULLY_TEST(bm1);
    if (ret != 0) {
        LOG_TEST_FAIL("bm1\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm1\n");
    }
    if (((unsigned char*)(bm1->buffer))[1] != 0x01
        || ((unsigned char*)(bm1->buffer))[0] != 0xf0) {
        LOG_TEST_FAIL("bm1, %#X %#X\n", ((unsigned char*)(bm1->buffer))[1], ((unsigned char*)(bm1->buffer))[0]);
    } else {
        LOG_TEST_PASS("bm1\n");
    }
    bitmap_clear_all(bm1);
    bitmap_set_block(bm1, 8, 8);    // 0x01, 0x00
    ret = BITMAP_FULLY_TEST(bm1);
    if (ret != 0) {
        LOG_TEST_FAIL("bm1\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm1\n");
    }
    if (((unsigned char*)(bm1->buffer))[1] != 0x01 
        || ((unsigned char*)(bm1->buffer))[0] != 0x00) {
        LOG_TEST_FAIL("bm1, %#X %#X\n", ((unsigned char*)(bm1->buffer))[1], ((unsigned char*)(bm1->buffer))[0]);
    } else {
        LOG_TEST_PASS("bm1\n");
    }
    bitmap_clear_all(bm1);
    bitmap_set_block(bm1, 5, 11);    // 0x0f, 0xe0
    ret = BITMAP_FULLY_TEST(bm1);
    if (ret != 0) {
        LOG_TEST_FAIL("bm1\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm1\n");
    }
    if (((unsigned char*)(bm1->buffer))[1] != 0x0f 
        || ((unsigned char*)(bm1->buffer))[0] != 0xe0) {
        LOG_TEST_FAIL("bm1, %#X %#X\n", ((unsigned char*)(bm1->buffer))[1], ((unsigned char*)(bm1->buffer))[0]);
    } else {
        LOG_TEST_PASS("bm1\n");
    }
    bitmap_clear_all(bm1);
    bitmap_set_block(bm1, 4, 15);    // 0xff, 0xf0
    ret = BITMAP_FULLY_TEST(bm1);
    if (ret != 0) {
        LOG_TEST_FAIL("bm1\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm1\n");
    }
    if (((unsigned char*)(bm1->buffer))[1] != 0xff 
        || ((unsigned char*)(bm1->buffer))[0] != 0xf0) {
        LOG_TEST_FAIL("bm1, %#X %#X\n", ((unsigned char*)(bm1->buffer))[1], ((unsigned char*)(bm1->buffer))[0]);
    } else {
        LOG_TEST_PASS("bm1\n");
    }
    bitmap_clear_all(bm1);
    bitmap_set_block(bm1, 15, 15);    // 0x80, 0x00
    ret = BITMAP_FULLY_TEST(bm1);
    if (ret != 0) {
        LOG_TEST_FAIL("bm1\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm1\n");
    }
    if (((unsigned char*)(bm1->buffer))[1] != 0x80 
        || ((unsigned char*)(bm1->buffer))[0] != 0x00) {
        LOG_TEST_FAIL("bm1, %#X %#X\n", ((unsigned char*)(bm1->buffer))[1], ((unsigned char*)(bm1->buffer))[0]);
    } else {
        LOG_TEST_PASS("bm1\n");
    }

    bitmap_clear_all(bm3);
    bitmap_set_block(bm3, (0 << 3) + 0, (3 << 3) + 5);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[3] != 0x3f 
        || ((unsigned char*)(bm3->buffer))[0] != 0xff
        || !__is_all_bytes_empty(bm3->buffer , 0)
        || !__is_all_bytes_full(bm3->buffer + 1, 1)
        || !__is_all_bytes_empty(bm3->buffer + 4, 13)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_clear_all(bm3);
    bitmap_set_block(bm3, (7 << 3) + 4, (16 << 3) + 7);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[16] != 0xff 
        || ((unsigned char*)(bm3->buffer))[7] != 0xf0
        || !__is_all_bytes_empty(bm3->buffer , 7)
        || !__is_all_bytes_full(bm3->buffer + 8, 8)
        || !__is_all_bytes_empty(bm3->buffer + 16, 0)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_clear_all(bm3);
    bitmap_set_block(bm3, (6 << 3) + 3, (7 << 3) + 5);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[7] != 0x3f 
        || ((unsigned char*)(bm3->buffer))[6] != 0xf8
        || !__is_all_bytes_empty(bm3->buffer , 6)
        || !__is_all_bytes_full(bm3->buffer + 7, 0)
        || !__is_all_bytes_empty(bm3->buffer + 8, 9)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_clear_all(bm3);
    bitmap_set_block(bm3, (5 << 3) + 2, (5 << 3) + 6);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[5] != 0x7c
        || !__is_all_bytes_empty(bm3->buffer , 5)
        || !__is_all_bytes_empty(bm3->buffer + 6, 11)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_clear_all(bm3);
    bitmap_set_block(bm3, (6 << 3) + 5, (11 << 3) + 6);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[11] != 0x7f 
        || ((unsigned char*)(bm3->buffer))[6] != 0xe0
        || !__is_all_bytes_empty(bm3->buffer , 6)
        || !__is_all_bytes_full(bm3->buffer + 7, 4)
        || !__is_all_bytes_empty(bm3->buffer + 12, 5)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_clear_all(bm3);
    bitmap_set_block(bm3, (3 << 3) + 0, (5 << 3) + 3);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[5] != 0x0f
        || ((unsigned char*)(bm3->buffer))[3] != 0xff
        || !__is_all_bytes_empty(bm3->buffer , 3)
        || !__is_all_bytes_full(bm3->buffer + 4, 1)
        || !__is_all_bytes_empty(bm3->buffer + 6, 11)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_clear_all(bm3);
    bitmap_set_block(bm3, (3 << 3) + 0, (5 << 3) + 7);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[5] != 0xff
        || ((unsigned char*)(bm3->buffer))[3] != 0xff
        || !__is_all_bytes_empty(bm3->buffer , 3)
        || !__is_all_bytes_full(bm3->buffer + 4, 1)
        || !__is_all_bytes_empty(bm3->buffer + 6, 11)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_clear_all(bm3);
    bitmap_set_block(bm3, (4 << 3) + 6, (7 << 3) + 7);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[7] != 0xff
        || ((unsigned char*)(bm3->buffer))[4] != 0xc0
        || !__is_all_bytes_empty(bm3->buffer , 4)
        || !__is_all_bytes_full(bm3->buffer + 5, 2)
        || !__is_all_bytes_empty(bm3->buffer + 8, 9)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_clear_all(bm3);
    bitmap_set_block(bm3, (0 << 3) + 0, (0 << 3) + 0);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[0] != 0x01
        || !__is_all_bytes_empty(bm3->buffer + 1, 16)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_clear_all(bm3);
    bitmap_set_block(bm3, (16 << 3) + 7, (16 << 3) + 7);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[16] != 0x80
        || !__is_all_bytes_empty(bm3->buffer, 16)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    
    /// 清除一块，并测试。
    bitmap_set_all(bm0);
    bitmap_clear_block(bm0, 0, 5);    // 0x3f
    ret = BITMAP_FULLY_TEST(bm0);
    if (ret != 0) {
        LOG_TEST_FAIL("bm0\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm0\n");
    }
    if (*(unsigned char*)(bm0->buffer) != (unsigned char)(~0x3f)) {
        LOG_TEST_FAIL("bm0, %#X\n", *(unsigned char*)(bm0->buffer));
    } else {
        LOG_TEST_PASS("bm0\n");
    }
    bitmap_set_all(bm0);
    bitmap_clear_block(bm0, 3, 6);    // 0x78
    ret = BITMAP_FULLY_TEST(bm0);
    if (ret != 0) {
        LOG_TEST_FAIL("bm0\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm0\n");
    }
    if (*(unsigned char*)(bm0->buffer) != (unsigned char)(~0x78)) {
        LOG_TEST_FAIL("bm0, %#X\n", *(unsigned char*)(bm0->buffer));
    } else {
        LOG_TEST_PASS("bm0\n");
    }
    bitmap_set_all(bm0);
    bitmap_clear_block(bm0, 2, 7);    // 0xfc
    ret = BITMAP_FULLY_TEST(bm0);
    if (ret != 0) {
        LOG_TEST_FAIL("bm0\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm0\n");
    }
    if (*(unsigned char*)(bm0->buffer) !=  (unsigned char)(~0xfc)) {
        LOG_TEST_FAIL("bm0, %#X\n", *(unsigned char*)(bm0->buffer));
    } else {
        LOG_TEST_PASS("bm0\n");
    }
    bitmap_set_all(bm0);
    bitmap_clear_block(bm0, 0, 7);    // 0xff
    ret = BITMAP_FULLY_TEST(bm0);
    if (ret != 0) {
        LOG_TEST_FAIL("bm0\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm0\n");
    }
    if (*(unsigned char*)(bm0->buffer) !=  (unsigned char)(~0xff)) {
        LOG_TEST_FAIL("bm0, %#X\n", *(unsigned char*)(bm0->buffer));
    } else {
        LOG_TEST_PASS("bm0\n");
    }
    bitmap_set_all(bm0);
    bitmap_clear_block(bm0, 3, 3);    // 0x08
    ret = BITMAP_FULLY_TEST(bm0);
    if (ret != 0) {
        LOG_TEST_FAIL("bm0\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm0\n");
    }
    if (*(unsigned char*)(bm0->buffer) !=  (unsigned char)(~0x08)) {
        LOG_TEST_FAIL("bm0, %#X\n", *(unsigned char*)(bm0->buffer));
    } else {
        LOG_TEST_PASS("bm0\n");
    }

    bitmap_set_all(bm1);
    bitmap_clear_block(bm1, 0, 12);    // 0x1f, 0xff
    ret = BITMAP_FULLY_TEST(bm1);
    if (ret != 0) {
        LOG_TEST_FAIL("bm1\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm1\n");
    }
    if (((unsigned char*)(bm1->buffer))[1] !=  (unsigned char)(~0x1f) 
        || ((unsigned char*)(bm1->buffer))[0] !=  (unsigned char)(~0xff)) {
        LOG_TEST_FAIL("bm1, %#X %#X\n", ((unsigned char*)(bm1->buffer))[1], ((unsigned char*)(bm1->buffer))[0]);
    } else {
        LOG_TEST_PASS("bm1\n");
    }
    bitmap_set_all(bm1);
    bitmap_clear_block(bm1, 4, 8);    // 0x01, 0xf0
    ret = BITMAP_FULLY_TEST(bm1);
    if (ret != 0) {
        LOG_TEST_FAIL("bm1\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm1\n");
    }
    if (((unsigned char*)(bm1->buffer))[1] !=  (unsigned char)(~0x01)
        || ((unsigned char*)(bm1->buffer))[0] !=  (unsigned char)(~0xf0)) {
        LOG_TEST_FAIL("bm1, %#X %#X\n", ((unsigned char*)(bm1->buffer))[1], ((unsigned char*)(bm1->buffer))[0]);
    } else {
        LOG_TEST_PASS("bm1\n");
    }
    bitmap_set_all(bm1);
    bitmap_clear_block(bm1, 8, 8);    // 0x01, 0x00
    ret = BITMAP_FULLY_TEST(bm1);
    if (ret != 0) {
        LOG_TEST_FAIL("bm1\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm1\n");
    }
    if (((unsigned char*)(bm1->buffer))[1] !=  (unsigned char)(~0x01) 
        || ((unsigned char*)(bm1->buffer))[0] !=  (unsigned char)(~0x00)) {
        LOG_TEST_FAIL("bm1, %#X %#X\n", ((unsigned char*)(bm1->buffer))[1], ((unsigned char*)(bm1->buffer))[0]);
    } else {
        LOG_TEST_PASS("bm1\n");
    }
    bitmap_set_all(bm1);
    bitmap_clear_block(bm1, 5, 11);    // 0x0f, 0xe0
    ret = BITMAP_FULLY_TEST(bm1);
    if (ret != 0) {
        LOG_TEST_FAIL("bm1\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm1\n");
    }
    if (((unsigned char*)(bm1->buffer))[1] !=  (unsigned char)(~0x0f) 
        || ((unsigned char*)(bm1->buffer))[0] != (unsigned char)(~0xe0)) {
        LOG_TEST_FAIL("bm1, %#X %#X\n", ((unsigned char*)(bm1->buffer))[1], ((unsigned char*)(bm1->buffer))[0]);
    } else {
        LOG_TEST_PASS("bm1\n");
    }
    bitmap_set_all(bm1);
    bitmap_clear_block(bm1, 4, 15);    // 0xff, 0xf0
    ret = BITMAP_FULLY_TEST(bm1);
    if (ret != 0) {
        LOG_TEST_FAIL("bm1\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm1\n");
    }
    if (((unsigned char*)(bm1->buffer))[1] != (unsigned char)(~0xff) 
        || ((unsigned char*)(bm1->buffer))[0] != (unsigned char)(~0xf0)) {
        LOG_TEST_FAIL("bm1, %#X %#X\n", ((unsigned char*)(bm1->buffer))[1], ((unsigned char*)(bm1->buffer))[0]);
    } else {
        LOG_TEST_PASS("bm1\n");
    }
    bitmap_set_all(bm1);
    bitmap_clear_block(bm1, 15, 15);    // 0x80, 0x00
    ret = BITMAP_FULLY_TEST(bm1);
    if (ret != 0) {
        LOG_TEST_FAIL("bm1\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm1\n");
    }
    if (((unsigned char*)(bm1->buffer))[1] != (unsigned char)(~0x80) 
        || ((unsigned char*)(bm1->buffer))[0] != (unsigned char)(~0x00)) {
        LOG_TEST_FAIL("bm1, %#X %#X\n", ((unsigned char*)(bm1->buffer))[1], ((unsigned char*)(bm1->buffer))[0]);
    } else {
        LOG_TEST_PASS("bm1\n");
    }

    bitmap_set_all(bm3);
    bitmap_clear_block(bm3, (0 << 3) + 0, (3 << 3) + 5);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[3] != (unsigned char)(~0x3f) 
        || ((unsigned char*)(bm3->buffer))[0] != (unsigned char)(~0xff)
        || !__is_all_bytes_full(bm3->buffer , 0)
        || !__is_all_bytes_empty(bm3->buffer + 1, 1)
        || !__is_all_bytes_full(bm3->buffer + 4, 13)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_set_all(bm3);
    bitmap_clear_block(bm3, (7 << 3) + 4, (16 << 3) + 7);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[16] != (unsigned char)(~0xff) 
        || ((unsigned char*)(bm3->buffer))[7] != (unsigned char)(~0xf0)
        || !__is_all_bytes_full(bm3->buffer , 7)
        || !__is_all_bytes_empty(bm3->buffer + 8, 8)
        || !__is_all_bytes_full(bm3->buffer + 16, 0)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_set_all(bm3);
    bitmap_clear_block(bm3, (6 << 3) + 3, (7 << 3) + 5);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[7] != (unsigned char)(~0x3f) 
        || ((unsigned char*)(bm3->buffer))[6] != (unsigned char)(~0xf8)
        || !__is_all_bytes_full(bm3->buffer , 6)
        || !__is_all_bytes_empty(bm3->buffer + 7, 0)
        || !__is_all_bytes_full(bm3->buffer + 8, 9)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_set_all(bm3);
    bitmap_clear_block(bm3, (5 << 3) + 2, (5 << 3) + 6);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[5] != (unsigned char)(~0x7c)
        || !__is_all_bytes_full(bm3->buffer , 5)
        || !__is_all_bytes_full(bm3->buffer + 6, 11)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_set_all(bm3);
    bitmap_clear_block(bm3, (6 << 3) + 5, (11 << 3) + 6);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[11] != (unsigned char)(~0x7f) 
        || ((unsigned char*)(bm3->buffer))[6] != (unsigned char)(~0xe0)
        || !__is_all_bytes_full(bm3->buffer , 6)
        || !__is_all_bytes_empty(bm3->buffer + 7, 4)
        || !__is_all_bytes_full(bm3->buffer + 12, 5)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_set_all(bm3);
    bitmap_clear_block(bm3, (3 << 3) + 0, (5 << 3) + 3);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[5] != (unsigned char)(~0x0f)
        || ((unsigned char*)(bm3->buffer))[3] != (unsigned char)(~0xff)
        || !__is_all_bytes_full(bm3->buffer , 3)
        || !__is_all_bytes_empty(bm3->buffer + 4, 1)
        || !__is_all_bytes_full(bm3->buffer + 6, 11)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_set_all(bm3);
    bitmap_clear_block(bm3, (3 << 3) + 0, (5 << 3) + 7);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[5] != (unsigned char)(~0xff)
        || ((unsigned char*)(bm3->buffer))[3] != (unsigned char)(~0xff)
        || !__is_all_bytes_full(bm3->buffer , 3)
        || !__is_all_bytes_empty(bm3->buffer + 4, 1)
        || !__is_all_bytes_full(bm3->buffer + 6, 11)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_set_all(bm3);
    bitmap_clear_block(bm3, (4 << 3) + 6, (7 << 3) + 7);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[7] != (unsigned char)(~0xff)
        || ((unsigned char*)(bm3->buffer))[4] != (unsigned char)(~0xc0)
        || !__is_all_bytes_full(bm3->buffer , 4)
        || !__is_all_bytes_empty(bm3->buffer + 5, 2)
        || !__is_all_bytes_full(bm3->buffer + 8, 9)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_set_all(bm3);
    bitmap_clear_block(bm3, (0 << 3) + 0, (0 << 3) + 0);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[0] != (unsigned char)(~0x01)
        || !__is_all_bytes_full(bm3->buffer + 1, 16)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }
    bitmap_set_all(bm3);
    bitmap_clear_block(bm3, (16 << 3) + 7, (16 << 3) + 7);
    ret = BITMAP_FULLY_TEST(bm3);
    if (ret != 0) {
        LOG_TEST_FAIL("bm3\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else 
    {
        LOG_TEST_PASS("bm3\n");
    }
    if (((unsigned char*)(bm3->buffer))[16] != (unsigned char)(~0x80)
        || !__is_all_bytes_full(bm3->buffer, 16)) {
        LOG_TEST_FAIL("bm3\n");
    } else {
        LOG_TEST_PASS("bm3\n");
    }

    /// 清理工作
    DESTROY_BITMAP_WITH_PADDING(bm0);
    DESTROY_BITMAP_WITH_PADDING(bm1);
    DESTROY_BITMAP_WITH_PADDING(bm2);
    DESTROY_BITMAP_WITH_PADDING(bm3);
    DESTROY_BITMAP_WITH_PADDING(bm4);
    DESTROY_BITMAP_WITH_PADDING(bm5);
    DESTROY_BITMAP_WITH_PADDING(bm6);
    DESTROY_BITMAP_WITH_PADDING(bm7);
}

static void bitmap_check_test(void)
{
    unsigned int buffer[] = {
        0x003c001f, 0x0000fc00, 0xff0fffe0, 0x953300ff, 
        0x221aff00, 0x00ffff00, 0x001fff00, 0x1fe00000, 
        0x00000000, 0xffffffff, 0x1ff80000, 0x00000000
    };
    long boarder[] = {
        5, 18, 22, 42, 48, 69, 84, 88, 
        104, 112, 114, 116, 118, 120, 121, 122, 
        123, 124, 125, 127, 128, 136, 144, 145, 
        146, 147, 149, 153, 154, 157, 158, 168, 
        184, 200, 213, 245, 253, 288, 320, 339, 
        349, 384
    };
    long boarder_size = sizeof(boarder) / sizeof(unsigned long);
    long current = 0;
    long cnt = 0;
    struct bitmap *bm = CREATE_BITMAP_WITH_PADDING(sizeof(buffer));
    memcpy(bm->buffer, buffer, bm->map_size);
    int is_set = 1;
    int ret = BITMAP_FULLY_TEST(bm);
    if (ret != 0) {
        LOG_TEST_FAIL("failed to create bitmap!\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else {
        LOG_TEST_PASS("\n");
    }

    /// 按批完整地检查每个范围的位。
    is_set = 1;
    current = 0;
    for (cnt = 0; cnt < boarder_size; cnt++) {
        long current_size = boarder[cnt] - current;
        long set_size = 0;
        long unset_size = 0;
        if (is_set) {
            if (!bitmap_check_all_set(bm, current, boarder[cnt] - 1)) {
                LOG_TEST_FAIL("block is supposed to be fully set!\n");
                break;
            }
        } else {
            if (bitmap_check_any_set(bm, current, boarder[cnt] - 1)) {
                LOG_TEST_FAIL("block is supposed to not be any bit set!\n");
                break;
            }
        }

        is_set = !is_set;
        current = boarder[cnt];
    }
    if (cnt != boarder_size) {
        printf("cnt: %lu, current: %lu, boarder: %lu\n", 
                cnt, 
                current, 
                boarder[cnt]);
    } else {
        LOG_TEST_PASS("\n");
    }

    /// 按位完整地检查每个范围的位
    is_set = 1;
    current = 0;
    for (cnt = 0; cnt < boarder_size; cnt++) {
        long current_size = boarder[cnt] - current;
        long set_size = 0;
        long unset_size = 0;
        if (is_set) {
            for (int i = current; i < boarder[cnt]; i++) {
                if (!bitmap_check_bit(bm, i)) {
                    LOG_TEST_FAIL("bit %d is supposed to be set!\n", i);
                    break;
                }
            }
        } else {
            for (int i = current; i < boarder[cnt]; i++) {
                if (bitmap_check_bit(bm, i)) {
                    LOG_TEST_FAIL("bit %d is supposed to be clear!\n", i);
                    break;
                }
            }
        }

        is_set = !is_set;
        current = boarder[cnt];
    }
    if (cnt != boarder_size) {
        printf("cnt: %lu, current: %lu, boarder: %lu\n", 
                cnt, 
                current, 
                boarder[cnt]);
    } else {
        LOG_TEST_PASS("\n");
    }

    /// 清理工作
    DESTROY_BITMAP_WITH_PADDING(bm);
}

static void bitmap_iter_test(void)
{
    unsigned int buffer[] = {
        0x003c001f, 0x0000fc00, 0xff0fffe0, 0x953300ff, 
        0x221aff00, 0x00ffff00, 0x001fff00, 0x1fe00000, 
        0x00000000, 0xffffffff, 0x1ff80000, 0x00000000
    };
    long boarder[] = {
        0, 5, 18, 22, 42, 48, 69, 84, 88, 
        104, 112, 114, 116, 118, 120, 121, 122, 
        123, 124, 125, 127, 128, 136, 144, 145, 
        146, 147, 149, 153, 154, 157, 158, 168, 
        184, 200, 213, 245, 253, 288, 320, 339, 
        349, 384
    };
    long boarder_size = sizeof(boarder) / sizeof(long);
    long current = 0;
    long cnt = 0;
    struct bitmap *bm = CREATE_BITMAP_WITH_PADDING(sizeof(buffer));
    memcpy(bm->buffer, buffer, bm->map_size);
    int is_set = 1;
    int ret = BITMAP_FULLY_TEST(bm);
    if (ret != 0) {
        LOG_TEST_FAIL("failed to create bitmap!\n");
        SHOW_BITMAP_ERROR_INFO(ret);
    } else {
        LOG_TEST_PASS("\n");
    }
    size_t bsize = 0;

    current = bitmap_first_set_bit(bm);
    for (cnt = 0; cnt < (boarder_size - 1); cnt += 2) {
        if (current != (boarder[cnt] != 384 ? boarder[cnt] : -1)) {
            LOG_TEST_FAIL("failed to get to the right position!\n");
            printf("%lu %#X\n",boarder[cnt + 1] - current, buffer[current / 32]);
            break;
        }
        bsize = bitmap_sizeof_set_block(bm, current);
        if (bsize != (boarder[cnt + 1] - current)) {
            LOG_TEST_FAIL("wrong size! %zu\n", bsize);
            printf("%lu %#X\n",boarder[cnt + 1] - current, buffer[current / 32]);
            break;
        }

        current = bitmap_next_set_block(bm, current);
    }
    if (cnt != boarder_size - 1 || current != -1) {
        printf("cnt: %lu, current: %lu, boarder: %lu\n", cnt, current, boarder[cnt]);
    } else {
        LOG_TEST_PASS("\n");
    }


    current = bitmap_first_unset_bit(bm);
    for (cnt = 1; cnt < boarder_size; cnt += 2) {
        if (current != (boarder[cnt] != 384 ? boarder[cnt] : -1)) {
            LOG_TEST_FAIL("failed to get to the right position!\n");
            printf("%lu %#X\n",boarder[cnt + 1] - current, buffer[current / 32]);
            break;
        }
        bsize = bitmap_sizeof_unset_block(bm, current);
        if (bsize != (boarder[cnt + 1] - boarder[cnt])) {
            LOG_TEST_FAIL("wrong size! %zu\n", bsize);
            printf("%lu %#X\n",boarder[cnt + 1] - current, buffer[current / 32]);
            break;
        }

        current = bitmap_next_unset_block(bm, current);
    }
    if (cnt != boarder_size || current != -1) {
        printf("cnt: %lu, current: %lu, boarder: %lu\n", cnt, current, boarder[cnt % boarder_size]);
    } else {
        LOG_TEST_PASS("\n");
    }

    /// 清理工作
    DESTROY_BITMAP_WITH_PADDING(bm);
}

void bitmap_tests(void)
{
    printf("\n* bitmap_test:\n");
    bitmap_create_test();
    bitmap_basic_test();
    bitmap_check_test();
    bitmap_iter_test();
}
